package com.rlax.framework.support.file.oss;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FilenameUtils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.AccessControlList;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.jfinal.kit.PropKit;
import com.rlax.framework.support.file.FileInfo;
import com.rlax.framework.support.file.FileManager;
import com.rlax.framework.support.file.FileResult;

/**
 * 阿里云oss文件操作
 * @author Rlax
 *
 */
public class AliyunOssFileManager implements FileManager {

    private String endpoint;
    private String accessId;
    private String accessKey;
    private String bucket;

    public AliyunOssFileManager() {
	    endpoint = PropKit.get("file.oss.endpoint");
        accessId = PropKit.get("file.oss.accessId");
        accessKey = PropKit.get("file.oss.accessKey");
        bucket = PropKit.get("file.oss.bucket");
    }
    
    public AliyunOssFileManager(String endpoint, String accessId, String accessKey, String bucket) {
	    this.endpoint = endpoint;
	    this.accessId = accessId;
	    this.accessKey = accessKey;
	    this.bucket = bucket;
    }
    
	@Override
	public FileResult save(File file, String savePath) {
		if (savePath.startsWith("/")) {
			savePath = savePath.substring(1);
		}
		
		FileResult result = new FileResult();
		result.success();
		OSSClient client = null;
		try {
			client = new OSSClient(endpoint, accessId, accessKey);
			client.putObject(bucket, savePath, file);
		} catch (Exception e) {
			result.error();
		} finally {
			client.shutdown();
		}
		return result;
	}

	@Override
	public FileResult save(byte[] data, String savePath) {
		if (savePath.startsWith("/")) {
			savePath = savePath.substring(1);
		}
		
		FileResult result = new FileResult();
		result.success();
		OSSClient client = null;
		try {
			client = new OSSClient(endpoint, accessId, accessKey);
			client.putObject(bucket, savePath, new ByteArrayInputStream(data));
		} catch (Exception e) {
			result.error();
		} finally {
			client.shutdown();
		}
		return result;
	}

	@Override
	public FileResult save(InputStream is, String savePath) {
		if (savePath.startsWith("/")) {
			savePath = savePath.substring(1);
		}
		
		FileResult result = new FileResult();
		result.success();
		OSSClient client = null;
		try {
			client = new OSSClient(endpoint, accessId, accessKey);
			client.putObject(bucket, savePath, is);
		} catch (Exception e) {
			result.error();
		} finally {
			client.shutdown();
		}
		return result;
	}

	@Override
	public List<FileInfo> list(String dirPath) {
		List<FileInfo> resultList = new ArrayList<FileInfo>();
		
		OSSClient client = new OSSClient(endpoint, accessId, accessKey);
		ObjectListing objectListing = client.listObjects(bucket, dirPath);
		
		List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
		for (OSSObjectSummary s : sums) {
			FileInfo info = new FileInfo();
			info.setBucketName(s.getBucketName());
			info.setKey(s.getKey());
			info.setName(FilenameUtils.getBaseName(s.getKey()));
			info.setExt(FilenameUtils.getExtension(s.getKey()));
			info.setSize(s.getSize());
			info.setLastModified(s.getLastModified());
			
			resultList.add(info);
		}
		
		client.shutdown();
		return resultList;
	}

	@Override
	public List<FileInfo> list() {
		List<FileInfo> resultList = new ArrayList<FileInfo>();
		
		OSSClient client = new OSSClient(endpoint, accessId, accessKey);
		ObjectListing objectListing = client.listObjects(bucket);
		
		List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
		for (OSSObjectSummary s : sums) {
			FileInfo info = new FileInfo();
			info.setBucketName(s.getBucketName());
			info.setKey(s.getKey());
			info.setName(FilenameUtils.getBaseName(s.getKey()));
			info.setExt(FilenameUtils.getExtension(s.getKey()));
			info.setSize(s.getSize());
			info.setLastModified(s.getLastModified());
			
			resultList.add(info);
		}
		
		client.shutdown();
		return resultList;
	}

	@Override
	public String getDownloadEndpoint() {
		return PropKit.get("file.oss.download");
	}

	@Override
	public String getDownPathByKey(String key) {
		if (key.startsWith("/")) {
			key = key.substring(1);
		}
		
		OSSClient client = new OSSClient(endpoint, accessId, accessKey);
		String downUrl = null;
		if (client.doesObjectExist(bucket, key)) {
			AccessControlList acl = client.getBucketAcl(bucket);
			String grant = acl.getCannedACL().toString();
			// private、public-read、public-read-write
			if (grant.equals("private")) {
				downUrl = client.generatePresignedUrl(bucket, key, new Date(System.currentTimeMillis() + 3600 * 1000)).toExternalForm();
			} else {
				downUrl = getDownloadEndpoint() + "/" + key;
			}
		} else {
			return null;
		}

		return downUrl;
	}
}
